package k2platform.common.util;

import org.apache.curator.framework.recipes.cache.PathChildrenCache;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class PathWatcher<T> implements IWatcher {

    private String basePath;  //"reload" node is used to trig reload action
    private Map<String, T> childrenData;
    private PathChildrenCache pathCache;

    public PathWatcher() {
        this("");
    }

    public PathWatcher(String basePath) {
        super();
        childrenData = new ConcurrentHashMap<>();
        this.basePath = basePath;
    }

    public void setPathCache(PathChildrenCache pathCache) {
        this.pathCache = pathCache;
    }

    public void setBasePath(String basePath) {
        this.basePath = basePath;
    }

    public String getBasePath() {
        return this.basePath;
    }

    public void closePathCache() throws IOException {
        this.pathCache.close();
    }

    public T getChildData(String childName) {
        return childrenData.get(childName);
    }

    public Map<String, T> getChildrenData() {
        return childrenData;
    }

    public void clearChildrenData() {
        childrenData.clear();
    }

    public void clear() {
        clearChildrenData();
    }

    public void load(Map<String, byte[]> datas) {
        clearChildrenData();
        if (datas != null) {
            for (String childName : datas.keySet()) {
                if (!childName.equalsIgnoreCase(Constants.ZOOKEEPER_PATH_RELOAD_NODE)) {
                    T data = getDataHolder(datas.get(childName));
                    if (data != null)
                        childrenData.put(childName, data);
                }
            }
        }
    }

    public void update(String childName, byte[] data) {
        childrenData.put(childName, getDataHolder(data));
    }

    public void add(String childName, byte[] data) {
        childrenData.put(childName, getDataHolder(data));
    }

    public void remove(String childName) {
        childrenData.remove(childName);
    }

    public abstract T getDataHolder(byte[] data);
}
